#pragma once

#include <iostream>
#include <string>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <functional>

#include "Log.hpp"
#include "Socket.hpp"
#include "InetAddr.hpp"

using namespace socket_ns;
using func_t = std::function<std::string(std::string, bool&)>;   //线程执行任务类型




class TcpServer;
class ThreadData
{
public:
    ThreadData(socket_sprt fd, InetAddr client, TcpServer* ts) : _fd(fd), _client(client), _ts(ts)
    {
    }

public:
    socket_sprt _fd;
    InetAddr _client;
    TcpServer* _ts;
};
class TcpServer
{
public:
    TcpServer(int port, io_service_t service)
        : _localaddr("0", port) 
        , _listenfd(std::make_unique<TcpSocket>())
        , _service(service)
        , _isrunning(false)
    {
        _listenfd->BuildListenSocket(_localaddr);
    }

    ~TcpServer()
    {

    }


    static void* HandleSock(void* arg) //设置为static 保证参数没有this指针
    {
        pthread_detach(pthread_self());
        ThreadData* td = static_cast<ThreadData*> (arg);
        td->_ts->_service(td->_fd, td->_client);

        ::close(td->_fd->SockFd());
        delete td;  //client退出后，释放td
        return nullptr;
    }

    void Loop()
    {
        _isrunning = true;
        while (_isrunning)
        {
            // 客户端网络信息
            InetAddr peer;
            // 创建一个套接字用于服务器与客户端进行通信
            socket_sprt normalsock = _listenfd->Accepter(&peer);

            // 服务器通过多线程处理请求，主线程继续监听是否有新的客户端连接
            pthread_t t;
            ThreadData* td = new ThreadData(normalsock, InetAddr(peer), this);
            pthread_create(&t, nullptr, HandleSock, td);   
          
        }
        _isrunning = false;
    }
private:
    std::unique_ptr<Socket> _listenfd;
    InetAddr _localaddr;    // 服务器网络地址
    bool _isrunning;
    io_service_t _service;  // 回调函数
};